home *** CD-ROM | disk | FTP | other *** search
/ Cracking 2 / Cracking II..iso / Texty / crackme / SiFLyiNG_7.txt < prev    next >
Encoding:
Text File  |  1999-07-31  |  11.8 KB  |  290 lines

  1.  
  2.         SiFLyiNG
  3.                 Tutorial #7
  4.  
  5. ____________________________________________________________________________
  6.  
  7. Target          : ---===<<Crackme 1 by VisionZ>>===---
  8.                   d/l it on EB site : http://crackmes.cjb.net
  9. Protection type : Serial/Name
  10. Level           : not too easy, not too hard
  11. Tools needed    : SoftIce 3.xx
  12.                   Basis of cracking
  13.                   A brain
  14.                   Punk music
  15.                   Liters of beer
  16.                   I think that's enough ;)
  17.  
  18. ____________________________________________________________________________
  19.  
  20. Before beginning...
  21.  
  22.         This crackme is based on a serial/name protection. But the serial is
  23. not calculated from the original name. The name is slightly transformed, so
  24. that he contains only caracters between A and Z so it's transformed in upper
  25. case too. There are no obvious comparisons, but we can calculate the valid
  26. serial char per char with some simple equation... but you'll see :)
  27.         Time is money so let's start...
  28.  
  29. ____________________________________________________________________________
  30.  
  31. The essay...
  32.  
  33.         
  34.         You have to enter the name and serial in a TextBox. I put 'SiFLyiNG'
  35. as name and '12345678' as serial. Then let's bpx on hmemcpy in SoftIce
  36. and exit the debugger. There press the 'Check!' button and Boom you're back
  37. in SoftIce. There are two entries so press F5, so that the prog will get the
  38. serial. Then press F11 to return to the caller and F12 till you see :
  39.  
  40.         CRACKME 1!.text+XXXX at the bottom of the code window.
  41.  
  42.         There you see this first piece of code:
  43.  
  44. :004011DF push ecx                    ;'d ecx' and you'll see the entered code
  45. :004011E0 lea edx, dword ptr [esp+14]         
  46. :004011E4 mov ecx, esp                
  47. :004011E6 mov dword ptr [esp+1C], esp
  48. :004011EA push edx
  49. :004011EB Call 004016CA
  50. :004011F0 lea eax, dword ptr [esp+1C]
  51. :004011F4 mov ecx, ebp
  52. :004011F6 push eax
  53. :004011F7 call 004013D0   ; this call will transforms the name and will keep
  54.         ; only characters between A and Z or a and z. Moreover, it will
  55.         ; convert the transformed name to uppercase, i.e. 'SiFLyiNG' becomes
  56.         ; 'SIFLYING' and '123 <sErIaL> >=-' becomes 'SERIAL'.
  57. :004011FC push eax
  58. :004011FD lea ecx, dword ptr [esp+14]
  59. :00401201 mov [esp+28], 02
  60. :00401206 Call 004016C4
  61. :0040120B lea ecx, dword ptr [esp+18]
  62. :0040120F mov [esp+24], 01
  63. :00401214 Call 004016BE
  64. :00401219 mov ecx, dword ptr [esp+10] ; ECX points to the transformed name
  65. :0040121D mov edx, dword ptr [esp+14] ; EDX points to the serial
  66. :00401221 mov eax, dword ptr [ecx-08] ; EAX = lenght of transformed name 
  67. :00401224 mov ecx, dword ptr [edx-08] ; ECX = lenght of serial
  68. :00401227 cmp eax, ecx     ; comparison between the two lenghts
  69. :00401229 jne 0040135B     ;if len code and len name aren't equal => bad guy
  70. :0040122F cmp eax, 00000003 ; the lenght of the transformed code must be > 2
  71. :00401232 jl 0040135B  ; otherwise => bad cracker
  72. :00401238 push eax
  73. :00401239 Call 004016B8
  74. :0040123E mov esi, eax
  75. :00401240 mov eax, dword ptr [esp+14]
  76. :00401244 add esp, 00000004
  77. :00401247 xor ecx, ecx
  78. :00401249 mov edx, dword ptr [eax-08]
  79. :0040124C dec edx
  80. :0040124D test edx, edx
  81. :0040124F jle 00401288
  82.  
  83.         Oufff in my case i'm lucky because the entered name ('SiFLyiNG') and
  84. the entered serial ('12345678') have the same lenght so it won't jump to the
  85. bad cracker routine at 401229 and it won't jump at 401232 anymore. So we can
  86. trace on to the calculation/comparison routine of the serial. But let's
  87. remember that EAX points to the transformed name: 'SIFLYING'. Here begins
  88. a loop depending on the lenght of the transformed code:
  89.                                                             
  90. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  91. |:00401286(C)
  92. |
  93. :00401251 mov dl, byte ptr [ecx+eax]    ;dl=ASCII code of char(ECX)of name
  94. :00401254 mov bl, byte ptr [ecx+eax+01] ;bl=ASCII code of the next char
  95. :00401258 mov eax, dword ptr [esp+14]   ;eax points to the serial
  96. :0040125C movsx edx, dl                 ;edx=ASCII code of char(ECX) of name
  97. :0040125F movsx eax, byte ptr [ecx+eax] ;eax=ASCII code of char(ECX) of serial
  98. :00401263 lea eax, dword ptr [eax+edx-02] ;eax=eax+edx-2
  99. :00401267 cdq                           ;convert dword to quadword and edx=0
  100. :00401268 sub eax, edx                  ;eax=eax-edx=eax-0=eax each time
  101. :0040126A movsx edx, bl                 ;adx=bl
  102. :0040126D sar eax, 1                    ;eax=eax/2
  103. :0040126F inc eax                       ;eax = eax +1
  104. :00401270 sub edx, 00000002             ;edx = edx -2
  105. :00401273 cmp eax, edx                  ;eax and edx must be equal
  106. :00401275 sete al                       ;al=1 if equal (bad if al=0)
  107. :00401278 mov byte ptr [ecx+esi], al    ;stores al in an array
  108. :0040127B mov eax, dword ptr [esp+10]   ;eax points to the name
  109. :0040127F inc ecx                       ;increases the counter
  110. :00401280 mov edx, dword ptr [eax-08]   ;edx = len of transformed name
  111. :00401283 dec edx                       ;decreases edx => edx=edx-1
  112. :00401284 cmp ecx, edx                  ;while ecx<>len of name -1
  113. :00401286 jl 00401251                   ;keeps on the loop
  114.  
  115.         This loop is really important because it will allow us to find the
  116. first part of the good serial.
  117.         It depends on the lenght of the name - 1. So it will loop 8-1=7 times
  118. for 'SIFLYING'.
  119.         Let's summarize what happens: (TName = transformed name)
  120.  
  121.         ecx=(ASCII code of the char(ECX) of the TName + ASCII code of the
  122.     char(ECX) of the entered serial - 2) / 2 + 1
  123.  
  124.         edx=ASCII code of the char(ECX+1) of the TName - 2
  125.  
  126. And we should have: ecx=edx
  127. so if N1N2N3N4N5N6N7N8 are the ascii code of the characters of the TName
  128.   and S1S2S3S4S5S6S7S8 the ascii code of the characters of the Serial
  129.   then we obtain:
  130.  
  131. 1st loop:
  132.   ecx=(N1+S1-2)/2+1
  133.   edx=(N2-2)
  134.         and ecx=edx <=> (N1+S1-2)/2+1=N2-2 <=> N1+S1-2=2*(N2-3)
  135.         and finally, as we want to know the serial :
  136.                 S1 = 2*(N2-3)-N1+2 = 2*(N2-2)-N1
  137.  
  138.   and we're even able to make a general formula:
  139.  
  140.        For i=1 to len(TName)-1
  141.                 S(i) = 2*[N(i+1) -2]-N(i)
  142.        Next i
  143.  
  144.   this formula isn't applied to the last character of the name because N(i)
  145. exists but not N(i+1) bacause there are no char after the last character (
  146. besides, it wouldn't be the last char if there were one after :)
  147.  
  148.         We can now apply the formula to all the characters of 'SIFLYING'.
  149. We have first to convert the string to N1N2N3N4N5N6N7N8 (in decimalbase):
  150.  
  151.         N1='S'=83 ; N2='I'=73 ; N3='F'=70 ; N4='L'=76
  152.         N5='Y'=89 ; N6='I'=73 ; N7='N'=78 ; N8='G'=71
  153.  
  154.         We have all what is necessary to calculate the S1S2S3S4S5S6S7 chars
  155. which compose serial for 'SiFLyiNG'. (the last char S8 will be calculated
  156. later ...)
  157.  
  158.         S1 = 2*(N2-2)-N1 = 2*(73-2)-83 = 59 = ';'
  159.         S2 = 2*(N3-2)-N2 = 2*(70-2)-73 = 63 = '?'
  160.         S3 = 2*(N4-2)-N3 = 2*(76-2)-70 = 78 = 'N'
  161.         S4 = 2*(N5-2)-N4 = 2*(89-2)-76 = 98 = 'b'
  162.         S5 = 2*(N6-2)-N5 = 2*(73-2)-89 = 53 = '5'
  163.         S6 = 2*(N7-2)-N6 = 2*(78-2)-73 = 79 = 'O'
  164.         S7 = 2*(N8-2)-N7 = 2*(71-2)-78 = 60 = '<'
  165.  
  166.         But S8 is missing... nope... come back to SoftIce and go on tracing...
  167. just after the previous loop you find this code :
  168.  
  169. :00401288 movsx edx, byte ptr [ecx+eax] ;edx=value the last char of TName
  170. :0040128C movsx edi, byte ptr [eax+01]  ;edi=value of 2nd char of TName
  171. :00401290 mov eax, dword ptr [esp+14]   ;eax points to the entered serial
  172. :00401294 add edi, FFFFFFFE             ;edi=edi-2
  173. :00401297 movsx eax, byte ptr [ecx+eax] ;value of last char of entered serial
  174. :0040129B lea eax, dword ptr [eax+edx-02] ;eax=eax+edx-2
  175. :0040129F cdq                      ;converts dword to quadword and edx=0
  176. :004012A0 sub eax, edx             ;eax=eax-edx=eax
  177. :004012A2 sar eax, 1               ;eax=eax/2
  178. :004012A4 inc eax                  ;eax=eax+1
  179. :004012A5 cmp eax, edi             ;eax and edi must be equal
  180. :004012A7 sete dl                  ;dl=1 if equal (0 if bad guy)
  181. :004012AA mov byte ptr [ecx+esi], dl    ;stores dl in the array
  182.  
  183.         Hummm...it looks like the previous loop, doesn't it ? But this time
  184. it's no loop but the check of the last character of the entered serial.
  185.  
  186.         We have :
  187.  
  188.         eax= (ASCII code of last char of TName + ASCII code of last char of
  189.              entered serial - 2) / 2 + 1
  190.         edi= ASCII code of second char - 2
  191.  
  192.         ...and eax must be equal to edi to get dl=1. So here we got:
  193.  
  194.         (N8+S8-2)/2+1=N2-2 <=> S8 = 2*(N2-3)+2-N8 = 2*(N2-2)-N8
  195.  
  196.         and if we apply this we get:
  197.  
  198.                 S8 = 2*(73-2)-71 = 71 = 'G'
  199.  
  200.         If we trace on in SoftIce, we'll arrive in the checking proc which
  201. check all the values that were stored in the array. Remember these lines:
  202.     :00401278 mov byte ptr [ecx+esi], al    ;stores al in an array
  203. and :004012AA mov byte ptr [ecx+esi], dl    ;stores dl in the array
  204.  
  205.  where al (or dl for the last char) contains the result of the checking for
  206. each char of the Serial and are stored in [esi+ecx] where ecx is the counter
  207. and esi points to the array. The final part of the checking compares each
  208. value to 1. If one of them is 0, which means that the caracter of the serial
  209. was bad, then bl is set to 1 and it will jump at 4012D5. I'll let the code
  210. so that you can see by yourself the final comparison loop:
  211.  
  212. :004012AD mov eax, dword ptr [esp+10]
  213. :004012B1 xor dl, dl
  214. :004012B3 xor bl, bl
  215. :004012B5 mov eax, dword ptr [eax-08]
  216. :004012B8 xor ecx, ecx
  217. :004012BA test eax, eax
  218. :004012BC jle 00401319
  219.  
  220. Here begins the loop :
  221.  
  222. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  223. |:004012CD(C)
  224. |
  225. :004012BE cmp byte ptr [ecx+esi], 00
  226. :004012C2 je 004012C8 ;jump if bad char and if flag=0
  227. :004012C4 mov dl, 01  ;dl=1 and i'll jump to bad cracker at 4012D1
  228. :004012C6 jmp 004012CA
  229.  
  230. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  231. |:004012C2(C)
  232. |
  233. :004012C8 mov bl, 01 ;bl=1 and i'll jump to bad cracker at 4012D5
  234.  
  235. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  236. |:004012C6(U)
  237. |
  238. :004012CA inc ecx       ; increase the counter
  239. :004012CB cmp ecx, eax  ; are all value checked ?
  240. :004012CD jl 004012BE   ; if no, then jump
  241. :004012CF test dl, dl   ; is dl=1 ?
  242. :004012D1 je 00401319   ; if yes, jump to bad cracker
  243. :004012D3 test bl, bl   ; is bl=1 ?
  244. :004012D5 jne 00401319  ; if yes then jump to bad cracker
  245. :004012D7 Call 004016B2
  246. :004012DC push 00000066
  247. :004012DE push 0000000E
  248. :004012E0 push 00000066
  249. :004012E2 Call 004016AC
  250. :004012E7 push eax
  251.  
  252. * Reference To: USER32.LoadIconA, Ord:019Eh
  253.                                   |
  254. :004012E8 Call dword ptr [004021BC]  ;load the smiling icon
  255.  
  256.         Hey if the smiling icon is loaded, it means that we found the correct
  257. serial for the name :)
  258.         And crackme is cracked...
  259.         So the serial for 'SiFLyiNG' or 'SIFLYING' or '--=<SiFLyiNG>=--' is:
  260.                 ';?Nb5O<G'
  261.  
  262. ____________________________________________________________________________
  263.  
  264. The end...
  265.  
  266.         I hope you have followed me til here... if not try to read this again
  267. and if you finally have questions, critics, or anything else, just mail me. I
  268. know this tutorial is quite long, but if you look closer, you'll see that
  269. it's really not difficult... it just applies the formula. Now try to make a
  270. keygen (use the formula and remember the transformations on the name...). I
  271. have included mine in VB5 with this tut and the EXE too... You'll see by
  272. yourself.
  273.         Regards,
  274.  
  275.                 SiFLyiNG
  276.                         siflying@ifrance.com
  277.  
  278.     Greetings: ACiD BuRN, Eternal Bliss, Skymarshall, Lucifer48, Carpathia
  279.                 and all the authors of crackmes and tutorials...
  280.     and VisionZ for his crackme of course 
  281.  
  282.        
  283.  
  284.  
  285.  
  286.  
  287.         
  288.  
  289.  
  290.